﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TweetSharp;
using Bing;
using System.Net;
using Microsoft.AzureAD.XPrize.TwittOracle.Properties;
using System.IO;
using System.Reflection;
using CsvHelper;

namespace Microsoft.AzureAD.XPrize.TwittOracle.DataCollection
{
    class InvalidAccountsExtractor
    {
        private TwitterService service;

        public InvalidAccountsExtractor(TwitterService service)
        {
            this.service = service;
        }

        public void getInvalidAccounts()
        {
            // Open accounts_valid.txt and read twitter handles.
            string root_path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string valid_profiles_filename = Path.Combine(root_path, "Data", "accounts_valid.txt");
            StreamReader file = new StreamReader(valid_profiles_filename);

            string bookmarkFilePath = Path.Combine(root_path, "Data", "bookmark.txt");
            string bookmarkScreenName = null;
            try
            {
                StreamReader bookmarkFile = new StreamReader(bookmarkFilePath);
                bookmarkScreenName = bookmarkFile.ReadLine();
                bookmarkFile.Close();
            }
            catch (FileNotFoundException e)
            {
                // Do nothing
            }

            // for each accounts, use bing search APIs to get related accounts
            // Refer: http://blog.jongallant.com/2012/07/bing-search-api-azure-csharp.html#.UGi2Wk1JLDl
            var bing = new BingSearchContainer(
                new Uri("https://api.datamarket.azure.com/Bing/Search/")) { 
                Credentials = new NetworkCredential(Resources.bingApiKey, Resources.bingApiKey) };

            string outputFile = System.IO.Path.Combine(root_path, "Data", "accounts_invalid.csv");
            StreamWriter outfile = new StreamWriter(outputFile, true);
            var csvWriter = new CsvWriter(outfile);

            string screenName = null;
            // Move to the bookmark
            screenName = file.ReadLine();
            if (bookmarkScreenName != null)
            {
                while (!bookmarkScreenName.Equals(screenName))
                {
                    screenName = file.ReadLine();
                }
            }

            int totalInvalidCounter = 0;
            while (screenName != null)
            {
                Console.WriteLine("Screen name: " + screenName);
                // Book mark the screenName
                StreamWriter bookmarkFileWriter = new StreamWriter(bookmarkFilePath);
                bookmarkFileWriter.Write(screenName);
                bookmarkFileWriter.Close();

                var search_string = String.Format("site:twitter.com {0}", screenName);
                var query = bing.Web(search_string, null, null, null, null, null, null, null);
                var results = query.Execute();

                int invalidPerValidCounter = 0;
                int count = 0;
                int profileNullCount = 0;
                foreach(var result in results)
                {
                    count++;
                    var url = result.Url;
                    var invalidCandidateScreenName = Utils.GetScreenName(url);
                    if (!String.IsNullOrEmpty(invalidCandidateScreenName)
                        && !invalidCandidateScreenName.Equals(screenName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var profile = service.GetUserProfileFor(invalidCandidateScreenName);
                        if (profile != null && profile.IsVerified == false)
                        {
                            Utils.CsvWrite(csvWriter, profile);
                            invalidPerValidCounter++;
                            totalInvalidCounter++;
                        }
                        if (profile == null)
                            profileNullCount++;
                        if (profileNullCount > 2)
                            break;
                    }

                    if (invalidPerValidCounter == 3)
                        break;
                }
                
                if(totalInvalidCounter % 10 == 0)
                    Console.WriteLine(totalInvalidCounter);

                if (count < 2)
                {
                    Console.WriteLine("Bing blocking. Count of query results: " + count);
                    break;
                }

                if(totalInvalidCounter > 500)
                    break;

                if (profileNullCount > 2)
                {
                    Console.WriteLine("Twitter blocking. Null count: " + profileNullCount);
                    break;
                }

                screenName = file.ReadLine();
            }

            csvWriter.Dispose();
            outfile.Close();
            file.Close();
        }
    }
}
